﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using System.Reflection;

public class EventNotificationDispatcher
{
    /// <summary>
    /// 消息分发器单例
    /// </summary>
    private static EventNotificationDispatcher instance;
    public static EventNotificationDispatcher Instance
    {
        get
        {
            if (null == instance)
                instance = new EventNotificationDispatcher();
            return instance;
        }
        set
        {
            instance = value;
        }
    }
    /// <summary>
    /// 委托事件
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="sender"></param>
    /// <param name="evt"></param>
    public delegate void EventHandler<T>(object sender, T evt);
    /// <summary>
    /// 参数
    /// </summary>
    protected object[] param = new object[2];

    /// <summary>
    /// 注册事件字典
    /// </summary>
    public Dictionary<Type, List<object>> handlers = new Dictionary<Type, List<object>>();

    /// <summary>
    /// 注册事件
    /// </summary>
    /// <typeparam name="T">Class类型</typeparam>
    /// <param name="handler">函数</param>
    public void Register<T>(EventHandler<T> handler)
    {
        Debug.Log("注册事件:"+handler.Method.Name);
        Register(typeof(T),handler);        
    }

    private void Register<T>(Type EventType, EventHandler<T> handler)
    {
        if (!handlers.ContainsKey(EventType))
        {
            handlers.Add(EventType, new List<object>());
        }
        if (!handlers[EventType].Contains(handler))
        {
            handlers[EventType].Add(handler);
        }
    }

    /// <summary>
    /// 分发事件
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="sender"></param>
    /// <param name="evt"></param>
    public void Publish<T>(object sender,T evt)
    {
        Publish(null,typeof(T),evt);
    }

    /// <summary>
    /// 发送通知事件
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="sender"></param>
    /// <param name="EventType"></param>
    /// <param name="evt"></param>
    private void Publish<T>(object sender, Type EventType ,T evt)
    {
        if (handlers.ContainsKey(EventType))
        {
            Debug.Log("public event key:"+typeof(T));
            var _handlers = handlers[EventType];
            //移除所有的无效事件
            _handlers.RemoveAll(delegate (object handler) { return handler == null; });

            for (int i = 0; i < _handlers.Count; i++)
            {
                object handler = handlers[EventType][i];
                MethodInfo method = handler.GetType().GetMethod("Invoke");
                param[0] = sender;
                param[1] = evt;
                method.Invoke(handler, param);
            }
        }
        else
        {
            Debug.Log(string.Format("<color=red>未注册的Key:{0}</color>",EventType));
        }
    }


    /// <summary>
    /// 注销事件
    /// </summary>
    /// <typeparam name="T">类型</typeparam>
    /// <param name="handler">注册函数名</param>
    public void UnRegister<T>(EventHandler<T> handler)
    {
        UnRegister(typeof(T),handler);
    }

    private void UnRegister<T>(Type EventType, EventHandler<T> handler)
    {
        if (handlers.ContainsKey(EventType))
        {
            handlers[EventType].Remove(handler);
            Debug.Log("Remove Event:"+handler);

            if (0 == handlers[EventType].Count)//注册事件为空时，移除字典Key
            {
                handlers.Remove(EventType);
            }
        }
    }

    /// <summary>
    /// 清空注册事件
    /// </summary>
    public void Clear()
    {
        handlers.Clear();
    }
}
